package bootstrap.liftweb

import net.liftweb._
import common._
import http._
import auth.{AuthRole, userRoles, HttpBasicAuthentication}
import sitemap._
import diona.PublisherRestHelper
import diona.model.{PublisherSchema, CurrentUser, User}
import sitemap.Loc.{Hidden, If}
import squerylrecord.SquerylRecord
import org.squeryl.Session
import net.liftweb.squerylrecord.RecordTypeMode._
import diona.auth.{DropboxAuthorizer, GoogleOperations}
import org.squeryl.internals.DatabaseAdapter
import util.Props
import diona.search.engine.SearchTaskHandler
;

class Boot {

  def boot() {
     Logger.setup = Full(Log4j.withFile(getClass.getResource("/log4j.properties")))

    // where to search snippet
    LiftRules.addToPackages("diona")

    initDb()

    // Build SiteMap
    val entries = List(
      Menu.i("Home") / "index",
      //Menu.i("Uploaded images") / "imageViewer" / "images" >> loggedIn,
      Menu.i("Contacts") / "contacts" / "contactsList" >> Boot.loggedIn,
      Menu.i("My content") / "network" / "myContent" >> Boot.loggedIn,
      Menu.i("Search requests") / "requests" / "list" >> Boot.loggedIn submenus {
        Menu.i("Add search request") / "requests" / "registerRequest" >> Hidden
      },
      Menu.i("Show search result") / "requests" / "searchResults" >> Boot.loggedIn
//      Menu.i("Sentiments") / "network" / "sentiments"
    ) ::: User.sitemap

    LiftRules.setSiteMap(SiteMap(entries: _*))

    //Show the spinny image when an Ajax call starts
    LiftRules.ajaxStart = Full(() => LiftRules.jsArtifacts.show("ajax-loader").cmd)

    // Make the spinny image go away when it ends
    LiftRules.ajaxEnd = Full(() => LiftRules.jsArtifacts.hide("ajax-loader").cmd)

    // Force the request to be UTF-8
    LiftRules.early.append(_.setCharacterEncoding("UTF-8"))

    val restHelper = new PublisherRestHelper()

    LiftRules.ajaxPostTimeout = 30000
    LiftRules.dispatch.append(restHelper)
    LiftRules.dispatch.append(GoogleOperations.processToken)
    LiftRules.dispatch.append(GoogleOperations.redirectToAuthorization)
    LiftRules.dispatch.append(DropboxAuthorizer.processToken)
    LiftRules.dispatch.append(DropboxAuthorizer.redirectToAuthorization)
    LiftRules.statelessDispatchTable.append(restHelper)

    LiftRules.httpAuthProtectedResource.append(restHelper.protection)

    LiftRules.authentication = HttpBasicAuthentication("syf") {
      authFunc
    }
    LiftRules.htmlProperties.default.set((r:Req) => new Html5Properties(r.userAgent))
  }

  private val authFunc: PartialFunction[(String, String, Req), Boolean] = {
    case (userEmail, userPass, _) => {
      User.byEmail(userEmail).map {
        user =>
          if (user.password.match_?(userPass)) {
            User.logUserIn(user)
            userRoles(List(AuthRole("Default")))
            CurrentUser(user)
            true
          } else {
            false
          }
      } getOrElse false
    }
  }

  def initDb()
  {
    val driver: String = Props.get("jdbc.driver").open_!
    val url = Props.get("jdbc.url").open_!
    val user = Props.get("jdbc.user").open_!
    val password = Props.get("jdbc.password").open_!


    Class.forName(driver)
    val adapter = Class.forName(Props.get("squeryl.adapter").open_!).newInstance().asInstanceOf[DatabaseAdapter]

    SquerylRecord.initWithSquerylSession(
      Session.create(java.sql.DriverManager.getConnection(url, user, password), adapter)
    )

    inTransaction {
      try {
        PublisherSchema.drop
      } catch {
        case e:Exception => println("DB exists")
      }
    }
    inTransaction {
      PublisherSchema.create
    }
  }

  SearchTaskHandler.start()
}

object Boot
{
  lazy val loggedIn = If(User.loggedIn_? _, () => RedirectResponse("/user_mgt/login"))
}
